package com.google.code.p.restrpc.client.event;

import com.google.code.p.restrpc.AsyncRpcResult;
import com.google.code.p.restrpc.MutableAsyncRpcResult;
import com.google.code.p.restrpc.RpcContext;
import com.google.code.p.restrpc.RpcRequest;
import com.google.code.p.restrpc.core.async.AsyncRpcResultRetriever;
import com.google.code.p.restrpc.event.RpcEventCenter;

/**
 * @author dz
 */
public class AsyncRpcEventUtils {
    
    public static void publishAsyncRpcEvent(RpcContext context,
                                            RpcRequest rpcRequest) {
        StringBuilder sb = new StringBuilder();
        sb.append(rpcRequest.getProtocal().prefix())
          .append(rpcRequest.getAddress());
        if (rpcRequest.getPort() != 80) {
            sb.append(":").append(rpcRequest.getPort());
        }
        sb.append(rpcRequest.getContext())
          .append("/")
          .append(AsyncRpcResultRetriever.SERVICE_NAME);
        String queryUrl = sb.toString();
        
        RpcEventCenter.getInstance()
                      .publishEvent(new AsyncRpcEventObject(rpcRequest.getRequestId(),
                                                            queryUrl,
                                                            new DefaultAsyncRpcResultQuery(context,
                                                                                           rpcRequest,
                                                                                           queryUrl)));
    }
    
    static class DefaultAsyncRpcResultQuery implements AsyncRpcResultRetriever {
        
        private Class resultClazz;
        
        private AsyncRpcResultRetriever asyncRpcResultQuery;
        
        public DefaultAsyncRpcResultQuery(RpcContext rpcContext,
                                          RpcRequest rpcRequest,
                                          String queryUrl) {
            
            this.resultClazz = rpcRequest.getMethodName().getClass();
            this.asyncRpcResultQuery = rpcContext.getRpcProxy()
                                                 .createProxy(AsyncRpcResultRetriever.class,
                                                              queryUrl);
        }
        
        public AsyncRpcResult findById(String requestId) {
            AsyncRpcResult result = asyncRpcResultQuery.findById(requestId);
            if (result instanceof MutableAsyncRpcResult) {
                ((MutableAsyncRpcResult) result).setResultClazz(resultClazz);
            }
            return result;
        }
        
    }
    
}
